// exports.ResUtil = void 0;
// var $logManager = require("./LogManager");
// var $resKeeper = require("./ResKeeper");
// var a = (function () {
//     function e() {}
//     e.getResKeeper = function (t, o) {
//         if (t) {
//             return (
//                 t.getComponent($resKeeper.default) ||
//                 (o ? t.addComponent($resKeeper.default) : e.getResKeeper(t.parent, o))
//             );
//         } else {
//             return null;
//         }
//     };
//     e.assignWith = function (t, o, i) {
//         var a = e.getResKeeper(o, i);
//         if (a && t) {
//             return a.autoReleaseRes(t), t;
//         } else {
//             return $logManager.LogMgr.error("AssignWith " + t + " to " + o + " faile"), null;
//         }
//     };
//     e.instantiate = function (t) {
//         var o = cc.instantiate(t);
//         var i = e.getResKeeper(o, !0);
//         if (i) {
//             var a = o._prefab;
//             if (a) {
//                 var r = a.asset;
//                 i.autoReleaseRes(r);
//             } else {
//                 $logManager.LogMgr.warn("instantiate " + t + ", autoRelease failed, not found asset");
//             }
//         } else {
//             $logManager.LogMgr.warn("instantiate " + t + ", autoRelease failed, not found ResKeeper");
//         }
//         return o;
//     };
//     e.removeAllChildren = function (e, t) {
//         if (void 0 === t) {
//             t = !0;
//         }
//         if (t) {
//             var o = e.getComponentsInChildren($resKeeper.default);
//             for (var n = 0; n < o.length; n++) {
//                 o[n].node.destroy();
//             }
//         }
//         e.removeAllChildren(t);
//     };
//     e.removeFromParent = function (e, t) {
//         if (void 0 === t) {
//             t = !0;
//         }
//         if (t) {
//             var o = e.getComponentsInChildren($resKeeper.default);
//             for (var n = 0; n < o.length; n++) {
//                 o[n].node.destroy();
//             }
//         }
//         e.removeFromParent(t);
//     };
//     return e;
// })();
// exports.ResUtil = a;

// import { LogMgr } from "./LogManager";
// import ResKeeper from "./ResKeeper";

// /**
//  * 资源工具类
//  * 建议名称：ResourceUtil
//  */
// export class ResUtil {
//     constructor() { }

//     /**
//      * 获取资源管理器组件
//      * @param t - 目标节点
//      * @param o - 是否添加组件
//      * @returns 资源管理器组件或null
//      * 建议方法名：getResourceKeeper
//      */
//     static getResKeeper(t: cc.Node, o?: boolean): ResKeeper | null {
//         if (t) {
//             return (
//                 t.getComponent(ResKeeper) ||
//                 (o ? t.addComponent(ResKeeper) : ResUtil.getResKeeper(t.parent, o))
//             );
//         } else {
//             return null;
//         }
//     }

//     /**
//      * 分配资源并自动释放
//      * @param t - 资源
//      * @param o - 目标节点
//      * @param i - 是否添加组件
//      * @returns 资源或null
//      * 建议方法名：assignResourceWith
//      */
//     static assignWith(t: any, o: cc.Node, i?: boolean): any | null {
//         const a = ResUtil.getResKeeper(o, i);
//         if (a && t) {
//             a.autoReleaseRes(t);
//             return t;
//         } else {
//             LogMgr.error("AssignWith " + t + " to " + o + " failed");
//             return null;
//         }
//     }

//     /**
//      * 实例化资源并自动释放
//      * @param t - 预制资源
//      * @returns 实例化的节点
//      * 建议方法名：instantiateResource
//      */
//     static instantiate(t: cc.Prefab | cc.Node): cc.Node {
//         const o = cc.instantiate(t) as cc.Node;
//         const i = ResUtil.getResKeeper(o, true);
//         if (i) {
//             const a = o["_prefab"];
//             if (a) {
//                 const r = a.asset;
//                 i.autoReleaseRes(r);
//             } else {
//                 LogMgr.warn("instantiate " + t + ", autoRelease failed, not found asset");
//             }
//         } else {
//             LogMgr.warn("instantiate " + t + ", autoRelease failed, not found ResKeeper");
//         }
//         return o;
//     }

//     /**
//      * 移除所有子节点并自动释放资源
//      * @param e - 目标节点
//      * @param t - 是否销毁节点
//      * 建议方法名：removeAllChildrenAndRelease
//      */
//     static removeAllChildren(e: cc.Node, t: boolean = true): void {
//         if (t) {
//             const o = e.getComponentsInChildren(ResKeeper);
//             for (let n = 0; n < o.length; n++) {
//                 o[n].node.destroy();
//             }
//         }
//         e.removeAllChildren(t);
//     }

//     /**
//      * 从父节点移除并自动释放资源
//      * @param e - 目标节点
//      * @param t - 是否销毁节点
//      * 建议方法名：removeFromParentAndRelease
//      */
//     static removeFromParent(e: cc.Node, t: boolean = true): void {
//         if (t) {
//             const o = e.getComponentsInChildren(ResKeeper);
//             for (let n = 0; n < o.length; n++) {
//                 o[n].node.destroy();
//             }
//         }
//         e.removeFromParent(t);
//     }
// }


import { LogMgr } from "./LogManager";
import ResKeeper from "./ResKeeper";

/**
 * 资源工具类
 * 建议名称：ResourceUtil
 */
export class ResourceUtil {
    constructor() { }

    /**
     * 获取资源管理器组件
     * @param targetNode - 目标节点
     * @param shouldAddComponent - 是否添加组件
     * @returns 资源管理器组件或null
     * 建议方法名：getResourceKeeper
     */
    static getResKeeper(targetNode: cc.Node, shouldAddComponent?: boolean): ResKeeper | null {
        if (targetNode) {
            const resKeeper = targetNode.getComponent(ResKeeper);
            if (resKeeper) {
                return resKeeper;
            } else if (shouldAddComponent) {
                return targetNode.addComponent(ResKeeper);
            } else {
                return ResourceUtil.getResKeeper(targetNode.parent, shouldAddComponent);
            }
        } else {
            return null;
        }
    }

    /**
     * 分配资源并自动释放
     * @param resource - 资源
     * @param targetNode - 目标节点
     * @param shouldAddComponent - 是否添加组件
     * @returns 资源或null
     * 建议方法名：assignResourceWith
     */
    static assignResourceWith(resource: any, targetNode: cc.Node, shouldAddComponent?: boolean): any | null {
        const resKeeper = ResourceUtil.getResKeeper(targetNode, shouldAddComponent);
        if (resKeeper && resource) {
            resKeeper.autoReleaseRes(resource);
            return resource;
        } else {
            LogMgr.error(`AssignWith ${resource} to ${targetNode} failed`);
            return null;
        }
    }

    /**
     * 实例化资源并自动释放
     * @param prefabOrNode - 预制资源
     * @returns 实例化的节点
     * 建议方法名：instantiateResource
     */
    static instantiate(prefabOrNode: cc.Prefab | cc.Node): cc.Node {
        const instantiatedNode = cc.instantiate(prefabOrNode) as cc.Node;
        const resKeeper = ResourceUtil.getResKeeper(instantiatedNode, true);
        if (resKeeper) {
            const prefabData = instantiatedNode["_prefab"];
            if (prefabData) {
                const asset = prefabData.asset;
                resKeeper.autoReleaseRes(asset);
            } else {
                LogMgr.warn(`instantiate ${prefabOrNode}, autoRelease failed, not found asset`);
            }
        } else {
            LogMgr.warn(`instantiate ${prefabOrNode}, autoRelease failed, not found ResKeeper`);
        }
        return instantiatedNode;
    }

    /**
     * 移除所有子节点并自动释放资源
     * @param targetNode - 目标节点
     * @param shouldDestroy - 是否销毁节点
     * 建议方法名：removeAllChildrenAndRelease
     */
    static removeAllChildrenAndRelease(targetNode: cc.Node, shouldDestroy: boolean = true): void {
        if (shouldDestroy) {
            const resKeepers = targetNode.getComponentsInChildren(ResKeeper);
            for (let i = 0; i < resKeepers.length; i++) {
                resKeepers[i].node.destroy();
            }
        }
        targetNode.removeAllChildren(shouldDestroy);
    }

    /**
     * 从父节点移除并自动释放资源
     * @param targetNode - 目标节点
     * @param shouldDestroy - 是否销毁节点
     * 建议方法名：removeFromParentAndRelease
     */
    static removeFromParentAndRelease(targetNode: cc.Node, shouldDestroy: boolean = true): void {
        if (shouldDestroy) {
            const resKeepers = targetNode.getComponentsInChildren(ResKeeper);
            for (let i = 0; i < resKeepers.length; i++) {
                resKeepers[i].node.destroy();
            }
        }
        targetNode.removeFromParent(shouldDestroy);
    }
}